using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace SIM_TPN_4
{
    public struct Pedido
    {
        public int dia;
        public int cantidad;
    }

    public partial class frmMontecarlo : Form
    {

        public frmMontecarlo()
        {
            InitializeComponent();
        }

        

        private void frmMontecarlo_Load(object sender, EventArgs e)
        {
            dgvProbDemanda.Rows.Add("0,05", "0,05", "0,00", "0,04", "0");
            dgvProbDemanda.Rows.Add("0,12", "0,17", "0,05", "0,16", "10");
            dgvProbDemanda.Rows.Add("0,18", "0,35", "0,17", "0,34", "20");
            dgvProbDemanda.Rows.Add("0,25", "0,60", "0,35", "0,59", "30");
            dgvProbDemanda.Rows.Add("0,22", "0,82", "0,60", "0,81", "40");
            dgvProbDemanda.Rows.Add("0,18", "1,00", "0,82", "0,99", "50");
        }

        private void btnCalcular_Click(object sender, EventArgs e)
        {
            switch (tabCtrlPoliticas.SelectedTab.Name)
            { 
                case "tabPA":
                    calculoPolitica("A");    
                    break;
                case "tabPB":
                    calculoPolitica("B"); 
                    break;
                case "tabPC":
                    calculoPolitica("C");
                    break;
            }
        }

        private void calculoPolitica(string politica)
        {
            dgvCalculoMontecarlo.Rows.Clear();

            Random rnd = new Random();
            double rnd_demanda = 0;
            double rnd_demora = 0;
            GenVarAle oGVA = new GenVarAle();

            int demanda = 0;
            int stock = 0;
            int faltante= 0;
            int pedido = 0;
            int demora = 0;

            double costo_almac = 0;
            double costo_falt = 0;
            double costo_pedido = 0;
            double costo_total = 0;

            double costo_almac_unidad = double.Parse(txtAlmacen.Text);
            double costo_falt_unidad = double.Parse(txtFaltante.Text);
            double lambda = double.Parse(txtMedia.Text);

            int cant_dias_pedido = 0;
            int cant_unid_pedido = 0;
            int cant_stock_minimo = 0;
            int cant_demanda_dias = 0;
            double porc_demanda = 0;

            Boolean ya_pidio = false;

            int suma_total_demanda = 0;
            int suma_total_faltante = 0;
            double suma_total_costo_alm = 0;
            double suma_total_costo_falt = 0;
            int suma_total_pedido = 0;
            int suma_total_demora = 0;
            double suma_total_costo_pedido = 0;
            double suma_total_costo_total = 0;

            List<Pedido> lstPedido = new List<Pedido>();
            
            switch (politica)
            {
                case "A":
                    cant_dias_pedido = int.Parse(txtCantPedDiasA.Text);
                    cant_unid_pedido = int.Parse(txtPedidoCantA.Text);
                    break;

                case "B":
                    cant_dias_pedido = int.Parse(txtCantPedDiasB.Text);
                    break;

                case "C":
                    cant_stock_minimo = int.Parse(txtStockMinimo.Text);
                    cant_demanda_dias = int.Parse(txtDiasDemanda.Text);
                    porc_demanda = double.Parse(txtPorcentajeDemanda.Text);                    
                    break;
            }
                  
            int acumulador_demanda = 0;

            for(int i=0; i<= int.Parse(txtCantDiasSim.Text);i++)
            {
                if (i == 0)
                {
                    demanda = 0;
                    stock = int.Parse(txtStockInicial.Text);
                    costo_almac = stock * costo_almac_unidad;
                    costo_total = costo_almac;
                }
                else
                {
                    rnd_demanda = Math.Round(rnd.NextDouble(), 2);
                    
                    //calculo de la demanda
                    for (int j = 0; j < dgvProbDemanda.Rows.Count; j++)
                    {
                        if (rnd_demanda <= double.Parse(dgvProbDemanda.Rows[j].Cells[3].Value.ToString()))
                        {
                            demanda = int.Parse(dgvProbDemanda.Rows[j].Cells[4].Value.ToString());
                            break;
                        }
                    }
                    pedido = 0;
                    costo_pedido = 0;
                    rnd_demora = 0;
                    demora = 0;

                    foreach (Pedido pedido_actual in lstPedido)
                    {
                        if (pedido_actual.dia == i)
                        {
                            stock += pedido_actual.cantidad;
                            ya_pidio = false;
                        }
                    }

                    stock = stock - demanda;

                    if (((politica == "A" || politica == "B") && i % cant_dias_pedido == 0) 
                        || (politica == "C" && stock <= cant_stock_minimo && ya_pidio == false))
                    {
                        rnd_demora = Math.Round(rnd.NextDouble(), 2);
                        demora = Convert.ToInt32(oGVA.DistPoisson(lambda));
                        switch (politica)
                        { 
                            case "A":
                                pedido = cant_unid_pedido;
                                ya_pidio = true;
                                break;

                            case "B":
                                pedido = acumulador_demanda;
                                acumulador_demanda = 0;
                                ya_pidio = true;
                                break;

                            case "C":
                                int dias_demanda = 0;
                                acumulador_demanda = 0;

                                if (ya_pidio) break;

                                dias_demanda =(i < cant_demanda_dias) ? i : cant_demanda_dias;

                                for (int j = i - dias_demanda; j < i; j++)
                                {
                                    acumulador_demanda += int.Parse(dgvCalculoMontecarlo.Rows[j].Cells[2].Value.ToString());
                                }
                                acumulador_demanda += demanda;
                                pedido = int.Parse((acumulador_demanda * porc_demanda / 100).ToString());
                                ya_pidio = true;

                                break;
                        }
                        
                        if (pedido != 0)
                        {
                            if (demora != 0)
                            {
                                Pedido oPedido = new Pedido();
                                oPedido.dia = i + demora;
                                oPedido.cantidad = pedido;
                                lstPedido.Add(oPedido);
                            }
                            else
                            {
                                stock += pedido;
                            }

                            if (pedido <= 20) costo_pedido = 20;
                            else if (pedido <= 40) costo_pedido = 25;
                            else costo_pedido = 30;
                        }
                        
                    }
                    else
                    {
                        if(politica == "B") acumulador_demanda += demanda;
                    }

                    //if (pedido != 0)
                    //{
                    //    foreach (Pedido pedido_actual in lstPedido)
                    //    {
                    //        if (pedido_actual.dia == i)
                    //        {
                    //            stock += pedido_actual.cantidad;
                    //            ya_pidio = false;
                    //        }
                    //    }
                    //}

                    //stock = stock - demanda;
                    faltante = 0;
                    if (stock < 0)
                    {
                        faltante = Math.Abs(stock);
                        stock = 0;
                    }
                    costo_almac = stock * costo_almac_unidad;
                    costo_falt = faltante * costo_falt_unidad;
                    costo_total = costo_almac + costo_falt + costo_pedido;

                }

                suma_total_demanda += demanda;
                suma_total_faltante += faltante;
                suma_total_costo_alm += costo_almac;
                suma_total_costo_falt += costo_falt;
                suma_total_pedido += pedido;
                suma_total_demora += demora;
                suma_total_costo_pedido += costo_pedido;
                suma_total_costo_total += costo_total;

                dgvCalculoMontecarlo.Rows.Add(i, rnd_demanda.ToString(), demanda, stock, faltante,
                    costo_almac, costo_falt, pedido, rnd_demora, demora, costo_pedido, costo_total);
                
            }

            txtTotDem.Text = suma_total_demanda.ToString();
            txtTotFal.Text = suma_total_faltante.ToString();
            txtTotCosAlm.Text = suma_total_costo_alm.ToString();
            txtTotCosFal.Text = suma_total_costo_falt.ToString();
            txtTotPed.Text = suma_total_pedido.ToString();
            txtTotDemora.Text = suma_total_demora.ToString();
            txtTotCosPed.Text = suma_total_costo_pedido.ToString();
            txtTotCosTot.Text = suma_total_costo_total.ToString();
            //dgvCalculoMontecarlo.Rows.Add("TOTALES", "", "", "", "",
                    //suma_total_costo_alm, suma_total_costo_falt, "", "", "", 
                    //suma_total_costo_pedido, suma_total_costo_total);
        }

    }
}